A computer application program usually includes a number of separate routines. Typically, the routines include a main program and several subsidiary routines referred to as objects, modules, or resources. Execution of the application program begins with the main program with calls being made to the subsidiary routines. To operate as a complete program, prior to execution these routines are linked together using a linker such as 386 link. The linker copies each of the routines into an executable file for the application program. The linker also provides each of the routines with information identifying the locations of other routines so that the routines can access each other. The executable file can then be loaded into the memory of a computer such that the application program can be executed by the computer according to the instructions in the routines.
A dynamic link library (DLL) is an executable module or routine containing services that application programs can call to perform useful tasks, e.g., directory searches, login commands, searching functions, character string manipulations, etc. DLLs exist primarily to provide services to application programs. These libraries play an important role in operating systems such as Windows and OS/2, which use them to make their services and resources available to application programs.
DLLs are similar to run-time libraries. The main difference between DLLs and run-time libraries is that DLLs are linked with the application program at run time, that is, when the computer is executing the application program, not when the application program files are linked with the linker. Linking a library with an application program at run time is referred to as dynamic linking; linking a library with an application program by using the linker is referred to as static linking. The discussion below focuses on the OS/2 operating system, but those of ordinary skill in the art will understand that the following discussion applies equally to other operating systems, such as Windows, which utilize DLLs.
To access a DLL at run time, the application program must be able to obtain information indicating where to find the DLL. One method provided by operating systems utilizing DLLs is to use an import library, or reference library, which contains information regarding where to locate the DLL at run time. During linking, the linker uses statically linked reference libraries to resolve references to external services. As noted above, when an application program desires a service from a static link library, the linker copies the code for that service into the application program's executable file. When the application program desires a service run from a DLL, however, the linker does not copy any code from the DLL. Instead, the linker searches all defined import or reference libraries to find one that contains the necessary information regarding location of the DLL. The linker copies the necessary information from the reference or import library to create a dynamic link between the executing application program and the DLL.
Performance analysis of a large software system with many DLLs can be very difficult. Many kinds of information are needed for the OS/2 operating system (OS/2 is a trademark of International Business Machines Corporation). A dekko hook/trace tool provides some, but not all of the needed information. The dekko hook/trace tool provides timing information on both operating system events as well as user-written events. The dekko hook/trace tool searches the syntax of a C source file for the entry and exits of routines and automatically inserts dekko hooks. One of the problems with the dekko hook/trace tool, and the suite of utilities that thus far have been written for it, is a mechanism to easily and automatically apply dekko hooks to new code has not been provided.
Other non-dekko based performance tools have tried to solve the automatic and ease of use hooking problem, but each is lacking in some respect. One particular problem is that prior art tools, including dekko, require some level of access to the source files used to build the executable of interest. Another problem is the processing overhead which prior art tools introduce in the software being analyzed. For example, the dekko hook/trace tool requires access to source code so it can be temporarily modified and recompiled. The IBMCPP Performance Analysis Tool requires a recompile of the source code with a compiler switch indicating to enable tracing. The IBMCPP Performance Analysis Tool is a tool which automatically hooks the entry and exits of routines and uses its own private trace log. MTrace is an instruction level trace tool which counts the number of instructions executed and accounts them to routine names. The MTrace tool does not require access to the source code, but does require a symbol table generated when the executable of interest was built and thus cannot be applied to off-the-shelf products. It is also difficult to set up and generates too much detail for some long-running scenarios. It does not provide real timing information, just instruction counts, and introduces a large amount of overhead. Each tool, dekko, IBMCPP, and MTrace, provide tracing of entries and exits of routines but exhibit common problems as identified above.
What is needed is a source code independent solution to the problem of automatic and easy hooking of new code, specifically addressing the hooking of entry and exit points of DLLs. What is also needed is a source code independent solution which does not introduce substantial processing overhead to the code being hooked.
The present invention may be utilized to perform analysis of DLL execution such as set forth in U.S. patent application Ser. No. 08/763,135, of common assignee herewith, to provide software routine timing information, to provide useful debugging information such as the status of certain parameters upon entry to or exit from software routines or to provide other similar information for program execution analysis.